package services

import (
	"fmt"
	"github.com/goravel/framework/facades"
	"github.com/goravel/framework/support/path"
	"github.com/spf13/cast"
	"goravel/app/models"
	"goravel/packages/socket/servers"
	"os"
	"strings"
)

// 批量执行
type BatchService struct {
	//Dependent services
	parsePrylockLogService   *ParsePrylockLogService
	parseKillLogService      *KillLogService
	parseLoginLogService     *LoginLogService
	parseChatLogService      *ChatLogService
	parseAdminLogService     *AdminLogService
	parseViolationLogService *ViolationLogService
	//parseCodeService         *ParseCodeService
	parseMineLogService     *MineLogService
	parseLandFlagLogService *LandFlagLogService
	parseTradeLogService    *TradeLogService
	parseBankLogService     *BankLogService
}

func (b *BatchService) NewBatchService() *BatchService {
	return &BatchService{
		//Inject services
	}
}
func (r *BatchService) Notice(user_id uint, message string) {
	var stage = "P:notice"
	nclient_id := facades.Cache().GetString(fmt.Sprintf("user:%d", user_id)) // 获取缓存
	servers.SendMessage2Client(nclient_id, cast.ToString(user_id), 200, message, &stage)
}

func (r *BatchService) ParseActionAll(foldPath string, config_id uint) {
	/**
	gameplay->pry
	gameplay->mine
	gameplay->flag->需要在这个地方再更新download_record的状态为已经解析
	economy->trade
	economy->bank->需要在这个地方再更新download_record的状态为已经解析
	*/

	var user_id uint
	facades.Orm().Query().Model(&models.Configuration{}).Where("id=?", config_id).Pluck("user_id", &user_id)

	r.Notice(user_id, fmt.Sprintf("开始解析|(0.10)"))

	/**
	 * 撬锁解析：关键词[LogMinigame]，文件夹关键字gameplay
	 */
	pry_fileList, rids := r.getLogFile(foldPath, "gameplay", config_id)
	var pry_msg1 = "撬锁解析-读取文件|(1:10)"
	r.Notice(user_id, pry_msg1)
	gps := r.parsePrylockLogService.NewParseLogService(foldPath, pry_fileList)
	var pry_msg2 = "撬锁解析-加载文件|(1:10)"
	r.Notice(user_id, pry_msg2)
	gps.ReadPryLockLine(config_id, rids)

	/**
	* 击杀解析
	 */
	kill_fileList, rids := r.getLogFile(foldPath, "kill", config_id)
	var kill_msg1 = "击杀解析-读取文件|(2:10)"
	r.Notice(user_id, kill_msg1)
	var kill_msg2 = "击杀解析-加载文件|(2:10)"
	r.Notice(user_id, kill_msg2)
	kps := r.parseKillLogService.NewKillLogService(foldPath, kill_fileList)
	kps.ReadKillLockLine(config_id, rids)

	/**
	* 登录登出解析
	 */

	log_fileList, rids := r.getLogFile(foldPath, "login", config_id)
	var log_msg1 = "登录解析-读取文件|(3:10)"
	r.Notice(user_id, log_msg1)
	login_ps := r.parseLoginLogService.NewLoginLogService(foldPath, log_fileList)
	var log_msg2 = "登录解析-加载文件|(3:10)"
	r.Notice(user_id, log_msg2)
	login_ps.ReadLoginLine(config_id, rids)

	/**
	* 聊天解析
	 */
	chat_fileList, rids := r.getLogFile(foldPath, "chat", config_id)
	var chat_msg1 = "聊天解析-读取文件|(4:10)"
	r.Notice(user_id, chat_msg1)
	chat_ps := r.parseChatLogService.NewChatLogService(foldPath, chat_fileList)
	var chat_msg2 = "聊天解析-加载文件|(4:10)"
	r.Notice(user_id, chat_msg2)
	chat_ps.ReadChatLine(config_id, rids)

	/**
	* 管理员日志解析
	 */
	admin_fileList, rids := r.getLogFile(foldPath, "admin", config_id)
	var admin_msg1 = "管理员解析-读取文件|(5:10)"
	r.Notice(user_id, admin_msg1)
	admin_ps := r.parseAdminLogService.NewAdminLogService(foldPath, admin_fileList)
	var admin_msg2 = "管理员解析-加载文件|(5:10)"
	r.Notice(user_id, admin_msg2)
	admin_ps.ReadAdminLine(config_id, rids)

	/**
	* 违规日志解析
	 */
	vi_fileList, rids := r.getLogFile(foldPath, "violations", config_id)
	var vi_msg1 = "违规解析-读取文件|(6:10)"
	r.Notice(user_id, vi_msg1)
	vi_ps := r.parseViolationLogService.NewViolationLogService(foldPath, vi_fileList)
	var vi_msg2 = "违规解析-加载文件|(6:10)"
	r.Notice(user_id, vi_msg2)
	vi_ps.ReadViolationLine(config_id, rids)

	/**
	* 解析地雷日志：关键词：[LogTrap]
	 */
	mine_fileList, rids := r.getLogFile(foldPath, "gameplay", config_id)
	var mine_msg1 = "地雷击杀解析-读取文件|(7:10)"
	r.Notice(user_id, mine_msg1)
	mine_ps := r.parseMineLogService.NewMineLogService(foldPath, mine_fileList)
	var mine_msg2 = "地雷击杀解析-加载文件|(7:10)"
	r.Notice(user_id, mine_msg2)
	mine_ps.ReadMineLine(config_id, rids)

	/**
	*领地旗：关键词：[LogBaseBuilding]
	 */
	flag_fileList, rids := r.getLogFile(foldPath, "gameplay", config_id)
	var flag_msg1 = "领地棋解析-读取文件|(8:10)"
	r.Notice(user_id, flag_msg1)
	flag_ps := r.parseLandFlagLogService.NewLandFlagLogService(foldPath, flag_fileList)
	var flag_msg2 = "领地棋解析-加载文件|(8:10)"
	r.Notice(user_id, flag_msg2)
	flag_ps.ReadLandFlagLine(config_id, rids)

	/**
	*交易：关键词：[Trade]
	 */

	trade_fileList, rids := r.getLogFile(foldPath, "economy", config_id)
	var trade_msg1 = "交易解析-读取文件|(9:10)"
	r.Notice(user_id, trade_msg1)
	trade_ps := r.parseTradeLogService.NewTradeLogService(foldPath, trade_fileList)
	var trade_msg2 = "交易解析-加载文件|(9:10)"
	r.Notice(user_id, trade_msg2)
	trade_ps.ReadTradeLine(config_id, rids)

	/*
	*银行：关键词：[Bank]
	 */

	bank_fileList, rids := r.getLogFile(foldPath, "economy", config_id)
	var bank_msg1 = "银行解析-读取文件|(10:10)"
	r.Notice(user_id, bank_msg1)
	bank_ps := r.parseBankLogService.NewBankLogService(foldPath, bank_fileList)
	var bank_msg2 = "银行解析-加载文件|(10:10)"
	r.Notice(user_id, bank_msg2)
	bank_ps.ReadBankLine(config_id, rids)

	var stage = "P:done"
	nclient_id := facades.Cache().GetString(fmt.Sprintf("user:%d", user_id)) // 获取缓存
	servers.SendMessage2Client(nclient_id, cast.ToString(user_id), 200, "任务完成", &stage)

}

// @袁浩：一次性获取所有文件，这个时候需要查询数据库，需要加载的文件才加载，不需要的不加载
func (r *BatchService) getLogFile(foldPath string, keyword string, config_id uint) ([]string, []uint) {
	pathname := path.Public(foldPath)
	//pathname为文件的的路径，获取该文件夹下的所有文件的名字，返回的names为切片类型
	files, _ := os.ReadDir(pathname)

	shouldLoadConfigs := []models.DownloadRecord{}
	facades.Orm().Query().Where("configuration_id=?", config_id).Where("file_name like ?", "%"+keyword+"%").
		Where("is_need_download_and_parse=?", 1).Find(&shouldLoadConfigs)
	retInts := []uint{}
	for _, shouldLoadConfig := range shouldLoadConfigs {
		retInts = append(retInts, shouldLoadConfig.ID)
	}
	var fileList []string
	for _, f := range files {
		if keyword != "" && !strings.Contains(f.Name(), keyword) {
			continue
		}
		if len(shouldLoadConfigs) > 0 {
			for _, shouldLoadConfig := range shouldLoadConfigs {
				if shouldLoadConfig.FileName == f.Name() {
					fileList = append(fileList, f.Name())
				}
			}
		}
	}
	return fileList, retInts
}
